# event listener
from direct.showbase import DirectObject
from Cube.command.QCommand.EventDefine import event_QCMD_MEMBERJOIN, event_QCMD_MEMBERLEAVE, \
                                              event_QCMD_MEMBERMOVE
# default configure
from Shell.configure.ConfigureAccess import ConfigureGet
# map
from Cube.map import MapMgrGet
from Cube.map import QMemberListMgr
# cmd
from Cube.command.QCommand import QCommand, QCmdMemberJoin, QCmdMemberLeave, QCmdClientSetup
# memType
from Cube.map import QMemberType
# test: command pipe
from Cube.command import CommandPipeReset, CommandPipeGet
# client setup
from Cube.utility.SerialNumberGen import SerialNumberGen


class GameLobbyBase(DirectObject.DirectObject):
    def __init__(self):
        # get current login configure
        self.LoginInfo = ConfigureGet("Login")
        self.ConnectType = self.LoginInfo["ConnectType"]
        # get current CmdInputPipe
        self.CmdInputPipe = CommandPipeGet()
        # command.Send
        self.CmdMemberJoinSend = QCmdMemberJoin().Send
        self.CmdMemberLeaveSend = QCmdMemberLeave().Send

        self.CmdInputPipe.CommandDispatchStart() # cmd pipe start

    def _MapStructureInit(self, bSuccess = True):
        self.MapMgrObj = MapMgrGet()
        if bSuccess:
            # get current map header
            self.MapHeader = self.MapMgrObj.CurrentMapHeader
            # load member list into MemberListMgr
            self.MemberListMgr = QMemberListMgr(self.MapHeader.MemberListGet())

            # link event handle
            self.accept(event_QCMD_MEMBERJOIN, self.MemberJoinHandle)
            self.accept(event_QCMD_MEMBERLEAVE, self.MemberLeaveHandle)
            self.accept(event_QCMD_MEMBERMOVE, self.MemberMoveHandle)

    def IsServerMode(self):
        ret = (self.ConnectType == "server")
        return ret

    def MyMemberIDGet(self):
        ret = self.MemberListMgr.MyMemberIDGet()
        return ret

    # override it
    def IPAddressGet(self):
        pass

    # internal function
    def _MyMemberIDSet(self, memberID):
        self.MemberListMgr.MyMemberIDSet(memberID)
        # set MyMemberID in QCommand klass
        QCommand.MyMemberID = memberID
        # add MyMemberID -> LinkID(None)

    def _MemberJoinCmdSend(self, memberID):
        self.CmdMemberJoinSend(memberName = self.LoginInfo["Nickname"],
                               memberType = QMemberType.HUMAN,
                               memID = memberID
                               )

    def _FirstValidMemberIDGet(self):
        memberID = self.MemberListMgr.FirstValidMemberIDGet()
        if memberID is None:
            raise 0, "Something wrong, no valid Member ID for server."
        return memberID

    # cmd handle
    def MemberJoinHandle(self, memberName, memberType, memberID):
        self.MemberListMgr.MemberJoin(memberName, memberType, memberID)
        # raise event at MemberListMgr.MemberJoin

    def MemberLeaveHandle(self, memberID):
        self.MemberListMgr.MemberLeave(memberID)
        # raise event at MemberListMgr.MemberLeave

    def MemberMoveHandle(self, memberID, move2TeamID):
        newMemberID = self.MemberListMgr.MemberMove(memberID, move2TeamID)
        if newMemberID is not None:
            if self.MemberListMgr.MyMemberIDGet() == memberID:
                self._MyMemberIDSet(newMemberID)
        # raise event
        self.MemberListMgr.MemberMoveEventRaise(memberID, newMemberID)
        return newMemberID

    def destroy(self, bReleaseMap=True):
        self.ignoreAll()
        if bReleaseMap:
            if self.MapMgrObj is not None:
                self.MapMgrObj.destroy()
            self.CmdInputPipe.destroy()
